home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / OWLSRC.PAK / GDIOBJEC.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  5.2 KB  |  219 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // Copyright (c) 1992, 1997 by Borland International, All Rights Reserved
  4. //
  5. //$Revision:   10.8  $
  6. //
  7. // Implementation of TGdiObject, abstract class for GDI objects that can be
  8. // selected into TDCs
  9. //----------------------------------------------------------------------------
  10. #include <owl/pch.h>
  11. #if !defined(OWL_GDIOBJEC_H)
  12. # include <owl/gdiobjec.h>
  13. #endif
  14.  
  15. OWL_DIAGINFO;
  16. DIAG_DEFINE_GROUP_INIT(OWL_INI, OwlGDI, 1, 0);
  17.                                    // General GDI diagnostic group
  18. DIAG_DEFINE_GROUP_INIT(OWL_INI, OwlGDIOrphan, 1, 0);
  19.                                    // Orphan control tracing group
  20.  
  21. //
  22. // TGdiObject's internal orphan control object, container and member functions
  23. //
  24. #include <classlib/bags.h>
  25.  
  26. #if defined(BI_NAMESPACE)
  27. namespace OWL {
  28. #endif
  29.  
  30. struct TObjInfo {
  31.   HANDLE            Handle;
  32.   TGdiObject::TType Type : 8;
  33.   int               RefCount : 8;
  34.  
  35.   TObjInfo() : Handle(0), Type(TGdiObject::None), RefCount(0) {}
  36.   TObjInfo(HANDLE handle) : Handle(handle) {}
  37.   TObjInfo(HANDLE handle, TGdiObject::TType type, int ref)
  38.     : Handle(handle), Type(type), RefCount(ref) {}
  39.   bool operator ==(const TObjInfo& other) const {
  40.     return other.Handle == Handle;
  41.   }
  42. };
  43.  
  44. typedef TBagAsVector<TObjInfo> TObjInfoBag;
  45. static TObjInfoBag* ObjInfoBag;
  46.  
  47. #if defined(__TRACE)
  48. const static char* ObjTypeStr[] = {
  49.   "?", "Pen", "Brush", "Font", "Palette", "Bitmap", "TextBrush", 0
  50. };
  51. #endif
  52.  
  53. #if defined(BI_NAMESPACE)
  54. } // namespace OWL
  55. #endif
  56.  
  57. //
  58. // Find a reference to a given handle in the ObjInfoBag
  59. //
  60. TObjInfo*
  61. TGdiObject::RefFind(HANDLE handle)
  62. {
  63.   if (!ObjInfoBag)
  64.     return 0;
  65.  
  66.   return handle ?
  67.            CONST_CAST(TObjInfo*,ObjInfoBag->Find(TObjInfo(handle))) : 0;
  68. }
  69.  
  70. //
  71. // Add an object reference entry into table, starting ref count at one
  72. //
  73. void
  74. TGdiObject::RefAdd(HANDLE handle, TGdiObject::TType type)
  75. {
  76. #if !defined(NO_GDI_SHARE_HANDLES)
  77.   if (handle) {
  78.     TObjInfo* member = RefFind(handle);
  79.     if (member)
  80.       member->RefCount++;
  81.     else {
  82.       if (!ObjInfoBag)
  83.         ObjInfoBag = new TObjInfoBag;
  84.       ObjInfoBag->Add(TObjInfo(handle, type, 1));
  85.     }
  86.   }
  87. #else
  88.   if (handle && !RefFind(handle)) {
  89.     if (!ObjInfoBag)
  90.       ObjInfoBag = new TObjInfoBag;
  91.     ObjInfoBag->Add(TObjInfo(handle, type, 1));
  92.   }
  93. #endif
  94. }
  95.  
  96. //
  97. // Remove an object reference entry from table
  98. //
  99. void
  100. TGdiObject::RefRemove(HANDLE handle)
  101. {
  102.   ObjInfoBag->Detach(TObjInfo(handle));
  103.   if (ObjInfoBag->GetItemsInContainer() == 0) {
  104.     delete ObjInfoBag;
  105.     ObjInfoBag = 0;
  106.   }
  107. }
  108.  
  109. //
  110. // Increment an object reference entry's ref count
  111. //
  112. void
  113. TGdiObject::RefInc(HANDLE handle)
  114. {
  115.   TObjInfo* member = RefFind(handle);
  116.   if (member)
  117.     member->RefCount++;
  118. }
  119.  
  120. //
  121. // Decrement an object reference entry's ref count.  Delete object if
  122. // refcount goes to zero.  Warn if deletion was/wasn't supposed to
  123. // happen and it didn't/did. Detach info if object was deleted.
  124. //
  125. void
  126. #if defined(__TRACE)
  127. TGdiObject::RefDec(HANDLE handle, bool wantDelete)
  128. #else
  129. TGdiObject::RefDec(HANDLE handle, bool)
  130. #endif
  131. {
  132.   TObjInfo* member = RefFind(handle);
  133.   if (member) {
  134.     bool needDelete = --(member->RefCount) == 0;
  135. #if defined(__TRACE)
  136.     if (needDelete != wantDelete) {
  137.       if (needDelete)
  138.         TRACEX(OwlGDIOrphan, 1, "Orphan" << ObjTypeStr[member->Type] <<
  139.                (uint)member->Handle << "Deleted")
  140.       else
  141.         TRACEX(OwlGDIOrphan, 1, ObjTypeStr[member->Type] <<
  142.                (uint)member->Handle << "Orphan")
  143.     }
  144. #endif
  145.     if (needDelete) {
  146.       if (!::DeleteObject(member->Handle))
  147.         TXGdi::Raise(IDS_GDIDELETEFAIL, member->Handle);
  148.       ObjInfoBag->Detach(*member);
  149.       if (ObjInfoBag->GetItemsInContainer() == 0) {
  150.         delete ObjInfoBag;
  151.         ObjInfoBag = 0;
  152.       }
  153.     }
  154.   }
  155. }
  156.  
  157. //
  158. // Return the reference count of a handle, -1 if not found
  159. //
  160. int
  161. TGdiObject::RefCount(HANDLE handle)
  162. {
  163.   TObjInfo* member = RefFind(handle);
  164.   if (member)
  165.     return member->RefCount;
  166.   return -1;
  167. }
  168.  
  169. //----------------------------------------------------------------------------
  170.  
  171. //
  172. //
  173. //
  174. #if defined(__TRACE) || defined(__WARN)
  175.   ostream& operator <<(ostream& os, const TGdiObject& gdiObject)
  176.   {
  177.     os << "@" << (void*)&gdiObject << " ";
  178.     os << '(';
  179. # if !defined(BI_NO_RTTI)
  180.       os << typeid(gdiObject).name() << ',';
  181. # endif
  182.     os << ')';
  183.     return os;
  184.   }
  185. #endif
  186.  
  187. //
  188. // TGdiObject constructors
  189. //
  190. TGdiObject::TGdiObject()
  191. {
  192.   // Handle must be set by derived class
  193.   TRACEX(OwlGDI, 2, "TGdiObject constructed " << *this);
  194. }
  195.  
  196. //
  197. // Create a wrapper for a given GDI object.
  198. //
  199. TGdiObject::TGdiObject(HANDLE handle, TAutoDelete autoDelete)
  200. :
  201.   TGdiBase(handle, autoDelete)
  202. {
  203.   // CheckValid();  // cant do this here, as derived class may set handle later
  204.   // Derived class must call RefAdd(Handle, type) if ShouldDelete
  205.   TRACEX(OwlGDI, 2, "TGdiObject constructed " << *this);
  206. }
  207.  
  208. //
  209. // Decrement the reference count on this object.
  210. //
  211. TGdiObject::~TGdiObject()
  212. {
  213.   if (ShouldDelete)
  214.     RefDec(Handle, true);
  215.   TRACEX(OwlGDI, 2, "TGdiObject destructed " << *this);
  216. }
  217.  
  218.  
  219.